#include <NTL/ZZ.h>
//#include "suborder_relations.hpp"
//#include "Timer_AE.h"


//#include <givaro/givinit.h>
//#include <givaro/givintfactor.h>
//#include <givaro/givtimer.h>
#include <sstream>
#include "end_ring_cp.h"



//using namespace ANTL;
using namespace std;
NTL_CLIENT
//using namespace Givaro;

/*
 * argv[1] : q
 * argv[2] : j
 * argv[3] : v
 * argv[4] : DK
 * argv[5] : max_p in FB
 */

int main (int argc, char *argv[])
{
  int k , FB_bound;
  ZZ D1,D2,v,p;
  double time1,time2;

  timerAE clock1,clock2;

  timerAE_start (clock1);
  timerAE_start (clock2);

#if 0
  {
    int FB_bound , sieve_flag;
    ZZ q , j , p1 , p2 , DK , v;
    stringstream strq , strj , strv , strD; //strp1 , strp2;

    strq  << argv[1] ; //"1606938044258990275550812343206050075546550943415909014478299" ;
    strj  << argv[2] ; //"602029056784703337842137145785931776902665506211718868393913";
    strv  << argv[3] ; 
    strD  << argv[4] ;
    //strp1 << "524287";
    //strp2 << "7195777666870732918103";


    strq  >> q;
    strj  >> j;
    strv  >> v;
    strD  >> DK;
    //strp1 >> p1;
    //strp2 >> p2;

    //v  = 2*127*p1*p2;
    //DK = -7;

    FB_bound = atoi ( argv[5] );

    if ( argc > 6 )
      sieve_flag = atoi( argv[6] );
    else
      sieve_flag = 0;

    end_ring_from_above ( q , j , v , DK , FB_bound , sieve_flag );
  }
#endif

  timerAE_run(clock1);
  /*
  for ( k = 0 ; k < 10 ; k++ )
  {
    int i;
    int m;

    m = test_drew ( argc, argv , (unsigned long)k);
    //printf ( "m = %d\n" , m );
    //m = 991;
    //for ( i = 0 ; i < m ; i++ ) if ( h[i] ) printf ("%ld^%s%ld ", ell[i], (hs[i]<0?"-":""), h[i]);
  }
  */
  //test_func_drew ( argc , argv );

  timerAE_stop(clock1);
  time1 = timerAE_get(clock1);


  timerAE_run(clock2);
  {
    stringstream strD1,strD2 ;
    int FB_size , P_once;
    long sieve_r;
    double Tol;

    strD1 << argv[1];
    strD2 << argv[1];

    strD1 >> D1;
    //cout << "D1 = " << D1 << endl;
    strD2 >> D2;
    //cout << "D2 = " << D2 << endl;
   
    v = to_ZZ(1);
    p = to_ZZ(1);

    FB_bound = atoi(argv[2]);
    Tol      = atof(argv[3]);
    sieve_r  = atol(argv[4]);
    P_once   = atoi(argv[5]);

    test_func_mike ( D1 , FB_bound, Tol , sieve_r , P_once );
    /*
    for ( FB_bound = 800 ; FB_bound < 1201 ; FB_bound += 200 )
    {
      // argv[2] = q
      // argv[3] = j
      // argv[4] = curve nb
      cout << "/home/biasse/Drew/zp_count_relation " << argv[2] << " " << argv[3] << " ";
      test_func_mike ( D1 , FB_bound );
      cout << "> /home/biasse/Drew/rel_count_curve_" << argv[4] << "_FB_" << FB_bound << endl;
    }
    */

    /*
    FB_size  = FB_size_from_FB_bound ( D1 , FB_bound );

    vec_long e,p_list;
    //find_relation_sieve(D1,D2,v,e,p_list, FB_size);
    find_relation_sieve_biasse(D1,D2,v,e,p_list, FB_size,10);

    //cout << "\nFound relation:" << endl;
    //cout << "primes: " << p_list << endl;
    //cout << "exp: " << e << endl;
    */
  }
  timerAE_stop(clock2);
  time2 = timerAE_get(clock2);

  cout << endl << "###############################################################################" << endl;
  cout << "D = " << D1 << endl;
  cout << "Log(D) = " << NumBits(D1) << endl;
  cout << "FB_bound = " << FB_bound << endl;
  cout << "Time Drew = " << time1 << endl << "Time sieve = " << time2 << endl;
  cout << "###############################################################################" << endl;

  return 0;
}
